package org.example.baizhi.aspects;


import com.fasterxml.jackson.databind.util.JSONPObject;
import jdk.internal.classfile.MethodSignature;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.example.baizhi.annotaions.RedisCache;
import org.example.baizhi.beans.RedisBean;
import org.example.baizhi.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.DigestUtils;
import redis.clients.jedis.Jedis;

import java.lang.reflect.Method;
import java.util.Set;

@Configuration
@Aspect
public class RedisCacheAspect {


    @Autowired
    private Jedis jedis;
    //开发环绕通知
    //execution 方法级别表达式   within 类级别表达式  @annotation类型切入点
    // @Around("execution(* org.example.baizhi.service.*ServiceImpl.find*(..))")
    @Around("@annotation(org.example.baizhi.annotaions.RedisCache)")
    public Object around(ProceedingJoinPoint pjp){

        RedisCache annotation = ((MethodSignature) pjp.getSignature()).getMethod().getAnnotation(RedisCache.class);
        String value1 = annotation.value1();
        System.out.println(value);
        //获取key
        String key = getHashKey(pjp);
        //获取jedis对象
        // Jedis jedis = new Jedis("192.168.1.109",7000);
        Object result = null;
        //判断redis中是否存在这个key
        // if(jedis.exists(key)){
        if(jedis.hexists(key, getHashValueKey(pjp))){
            System.out.println("redis中存在，直接获取响应");
            // String json = jedis.get(key);
            String json = jedis.hget(getHashKey(pjp), getHashValueKey(pjp));
            MethodSignature signature = (MethodSignature) pjp.getSignature();
            System.out.println(signature.getMethod().getReturnType());
            // result = JSONPObject.parseArray(json,User.class);
            result = JSONPObject.parseObject(json, signature.getMethod().getGenericReturnType());
        }else {
            System.out.println("redis中不存在，查询数据库");
            try{
                result = pjp.proceed();
                // jedis.set(key,JSONPObject.toJSONString(result));
                jedis.hset(getHashKey(pjp), getHashValueKey(pjp), JSONPObject.toJSONString(result));
            }catch (Throwable throwable){
                throwable.printStackTrace();
            }
        }
        return result;
    }


    //生成key方法
    // public String getKey(ProceedingJoinPoint pjp){
    //
    //     //类名
    //     String clazzName = pjp.getTarget().getClass().getName();
    //
    //     //对类型MD5
    //     String keyPrefix = DigestUtils.md5DigestAsHex(clazzName.getBytes());
    //
    //     //生成key
    //     StringBuilder builder = new StringBuilder();
    //
    //     //方法名
    //     String methodName = pjp.getSignature().getName();
    //     builder.append(clazzName).append(methodName);
    //     //参数
    //
    //     Object[] args = pjp.getArgs();
    //     for(Object arg : args){
    //         builder.append(arg) ;
    //      }
    //     String keySuffix = DigestUtils.md5DigestAsHex(builder.toString().getBytes());
    //     return keyPrefix+keySuffix;
    // }

    //生成Hashkey方法
    public String getHashKey(ProceedingJoinPoint pjp){
        //类名
        String clazzName = pjp.getTarget().getClass().getName();
        //对类型MD5
        String keyPrefix = DigestUtils.md5DigestAsHex(clazzName.getBytes());
        return keyPrefix;
    }

    //hash 中的value的key
    public String getHashValueKey(ProceedingJoinPoint pjp){
        //生成key
        StringBuilder builder = new StringBuilder();

        //方法名
        String methodName = pjp.getSignature().getName();
        builder.append(methodName);
        //参数

        Object[] args = pjp.getArgs();
        for(Object arg : args){
            builder.append(arg) ;
        }
        String keySuffix = DigestUtils.md5DigestAsHex(builder.toString().getBytes());
        return keySuffix;
    }




    /**
     用来维护增删改的缓存
     */
    // @After("execution(* org.example.baizhi.service.*ServiceImpl.save*(..)) && execution(* org.example.baizhi.service.*ServiceImpl.update*(..)) && execution(* org.example.baizhi.service.*ServiceImpl.delete*(..))")
    // @After("execution(* org.example.baizhi.service.*ServiceImpl.*(..))")
    //@After("execution(* org.example.baizhi.service.*ServiceImpl.*(..)) && !annotation(org.example.baizhi.annotations.RedisCache)")
    @After("execution(* org.example.baizhi.service.*ServiceImpl.*(..)) !org.example.baizhi.service.*ServiceImpl.find(..))")
    public void after(JoinPoint joinPoint){
        //获取类名
        String keyPrefix = DigestUtils.md5DigestAsHex(joinPoint.getTarget().getClass().getName().getBytes());
        System.out.println(keyPrefix);

        // Jedis jedis = new Jedis("192.168.1.100",6379);
        // Set<String> keys = jedis.keys("*");
        // for(String key : keys){
        //     if(key.startsWith(keyPrefix)){
        //         jedis.del(key);
        //     }
        // }
        jedis.del(keyPrefix);
    }
}
